Up until now, the Java story has largely been a client-side story. That's about to change. Now web servers can be extended through Java power just like web browser clients.
In the context of client-server software solutions--including the serving and browsing of Internet web pages--Java applets have enabled client browsers to extend their behavior by downloading compiled code from network servers. Applets have changed the nature and meaning of distributed computing. Applets have opened new worlds by enabling the convenient distribution of compiled code from a central server.
There's no reason that servers can't take advantage of Java in the same way that desktop applications have been able to take advantage of Java. To this end, JavaSoft has introduced server technology that is written in 100% Pure Java (tm) and that is capable of being extended dynamically by loading compiled Java code known as a servlet. While applets provide a way of dynamically extended the functionality of client-side browsers, servlets let you dynamically extend the functionality of network servers.
Programmers should think of servlets as server-side components. Servlets are to servers what applets are to browsers. Servlet code can be downloaded into a running server to extend its behavior in order to provide new, or temporary, services to network clients.
There are two sides to form processing:
First consider a form that looks like Figure 01.
Writing the CGI scripts to process this code could be quite complex. However writing a Java servlet class to handle the task is straightforward.
The following is an example of the HTML used to present the form to user. Note that it uses the POST method in HTTP. This is for two reasons. First, since this data is going to be stored in a database the GET method is inappropriate. Second, the POST method lets you pass much more data to the server than the GET method would. (GET methods are used for queries, and in some other places. Most forms should use POST.)
<html> <head><title>JDC Survey Number 1</title></head> <body> <form action=http://cool1:8080/servlet/JdcSurvey01 method=POST> <input type=hidden name=survey value=Survey01Results> <BR> <BR>How Many Employees in your Company?<BR> <BR> 1-100<input type=radio name=employee value=1-100> <BR> 100-200<input type=radio name=employee value=100-200> <BR> 200-300<input type=radio name=employee value=200-300> <BR> 300-400<input type=radio name=employee value=300-400> <BR> 500-more<input type=radio name=employee value=500-more> <BR> <BR>General Comments?<BR> <BR> <input type=text name=comment> <BR> <BR>What IDEs do you use?<BR> <BR> JavaWorkShop<input type=checkbox name=ide value=JavaWorkShop> <BR> J++<input type=checkbox name=ide value=J++> <BR> Cafe'<input type=checkbox name=ide value=Cafe'> <BR> <BR><input type=submit><input type=reset></form> </body></html>
This code file should be placed in the public_html
directory
immediately below the root directory where you installed your JavaServer.
The form specifies three basic questions to be answered by users. First,
the question "How Many Employees in your Company?" offers a set of five
radio buttons for potential responses.
<BR>How Many Employees in your Company?<BR> <BR> 1-100<input type=radio name=employee value=1-100> <BR> 100-200<input type=radio name=employee value=100-200> <BR> 200-300<input type=radio name=employee value=200-300> <BR> 300-400<input type=radio name=employee value=300-400> <BR> 500-more<input type=radio name=employee value=500-more>
Second, the question "General Comments?" provides a single text input field for the users to type in a general comment.
<BR>General Comments?<BR> <BR> <input type=text name=comment>Third, the question "What IDEs do you use?" provides a set of three check boxes. Unlike the radio buttons, these are not mutually exclusive choices as the users may use all three products: Java WorkShop, J++, and Cafe.
<BR>What IDEs do you use?<BR> <BR> JavaWorkShop<input type=checkbox name=ide value=JavaWorkShop> <BR> J++<input type=checkbox name=ide value=J++> <BR> Cafe'<input type=checkbox name=ide value=Cafe'>
Finally a Submit button is provided to cause the form to be submitted and processed when the user has finished answering questions. A Reset button appears next to the Submit button in case the user wants to reset all fields to the original default values.
<BR><input type=submit><input type=reset></form>
Once you press the Submit button, the data in the form is sent as a data stream to the servlet specified in the form tag at the top of the HTML file:
<form action=http://cool1:8080/servlet/JdcSurvey01 method=POST>This syntax is very similar to the way in which you would specify that data in the HTML form to be processed by a CGI script (whether Perl, shell, or compiled C program).
After submitting the form shown in Figure 01, the text in file
/tmp/Survey01Results.txt
on host cool1
should
look like this:
<BEGIN> ide: JavaWorkShop survey: Survey01Results employee: 500-more comment: Great Stuff! <END>
Also, after submitting the form, the JavaServer will display a new web
page based on the output written to the response argument passed to
the servlet's doPost
method. (A query form, using the GET
method, would call the doGet
method of the servlet.)
In this case a "thank you" message is displayed.
Here's the Java code required to process the form, once submitted, from the page
described by the TestJdcSurvey01.html
file.
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import sun.server.http.*; import sun.misc.*; import java.util.*; public class JdcSurvey01 extends HttpServlet { private String _baseDir; /** * Initialize the Servlet and set the html pages. * @param stub Arguments passed by the Servlet loader * @return void */ public void init (ServletConfig config) throws ServletException { super.init(config); _baseDir = config.getInitParameter ("baseDir"); } /** * Write survey results to output file in response * to the POSTed form. * @param request The Servlet request. * @param response The Servlet response. * @return void. */ public void doPost ( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { PrintWriter printWriter = null; FileWriter results = null; Enumeration values = request.getParameterNames(); PrintStream out = new PrintStream (response.getOutputStream()); String surveyName = request.getParameter ("survey"); response.setContentType ("text/html"); try { results = new FileWriter (_baseDir + System.getProperty ("file.separator") + surveyName + ".txt", true); printWriter = new PrintWriter (results); printWriter.println (""); while ( values.hasMoreElements() ) { String name, value; name = (String)values.nextElement(); value = request.getParameter (name); if ( name.compareTo ("submit") != 0 ) { printWriter.println (name + ": " + value); } } printWriter.println (" "); out.println ("Thank-You for participating"); } catch (IOException e) { e.printStackTrace(); out.println ( "A problem occured while recording your answers. " + "Please try again."); } try { if ( results != null ) { results.close(); } } catch (IOException e) { e.printStackTrace(); } out.close(); response.getOutputStream().close(); } }
This servlet source file, and the compiled servlet class, should also be
placed in the servlets
directory immediately below the
root directory where you installed your JavaServer. Before clients
can make use of the extended server functionality added by the
JdcSurvey01
servlet class, you will also have to install
the servlet using the JavaServer Administration Tool.
doPost
method of the JdcSurvey01
class.
First, two different output streams are opened for writing text to give feedback to the users and to record the results of the survey.
public void doPost ( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { PrintWriter printWriter = null; ... PrintStream out = new PrintStream (response.getOutputStream()); ... }Recall the the public interface for
PrintWriter
is the same as for
PrintStream
. The primary difference is the way that buffer flushing is
handled when println
is called. The main thing to keep in mind here
is that anything written to printWriter
will be saved in the
survey results file, while anything written to out
will be printed
on the HTML form automatically generated by the JavaServer as a
result of processing the form.
To allow the survey results to be written to a file a
FileWriter
object is associated with a
PrintWriter
object.
results = new FileWriter (_baseDir + System.getProperty ("file.separator") + surveyName + ".txt", true); printWriter = new PrintWriter (results);Recall that
_baseDir
holds the string that was passed in
as the value of the baseDir
property.
_baseDir = config.getInitParameter ("baseDir");The value of the
baseDir
property was set in the JavaServer
Administration Tool to baseDir=/tmp
when the
JdcSurvey01
was added to the list of supported servlets.
See Figure 06.
Thus the name of the file created by
results = new FileWriter (_baseDir + System.getProperty ("file.separator") + surveyName + ".txt", true);is
/tmp/Survey01Results.txt
since the value of the
surveyName
property was set TestJdcSurvey01.html
.
If you want to change the name of the output file, edit the above line accordingly.
Now output that is written to printWriter
such as
printWriter.println ("will be written to the file,"); ... printWriter.println (name + ": " + value); ... printWriter.println (" ");
/tmp/Survey01Results.txt
.
Output that is written to out
such as
out.println ("Thank-You for participating"); ... out.println ("A problem occured while recording your answers. Please try again.");will appear in the client's browser after the form has been processed and control returns from
JdcSurvey01.doPost
.
The main thing you need to know to understand how a servlet processes form
arguments is that input for the form processing is read from
the request argument to the doPost
method
and output is written
the response
argument to the doPost
method.
public void doPost ( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { ... }More specifically, the
request
method contains a list of
parameters that can be retrieved with the
HttpServletRequest::getParameterNames
method.
Enumeration values = request.getParameterNames();With the
values
enumeration object returned by this call, you can now
set up a loop to process each of the parameters passed by the HTML form
to the servlet doPost
routine:
while ( values.hasMoreElements() ) { ... }The name of the parameter is retrieved on each iteration by
Enumeration::nextElement
, while the associated value is
retrieved by HttpServletRequest::getParameter
, which
accepts the parameter name as an argument.
String name, value; name = (String)values.nextElement(); value = request.getParameter (name);The only value you don't want to print in the results file is the value of the "submit" parameter which is passed because submit was specified as a button in the html file. The servlet
doPost
routine weeds out this parameter with a simple
string comparison:
if ( name.compareTo ("submit") != 0 ) { printWriter.println (name + ": " + value); }You should now know enough to write simple servlets to extend your JavaServer to process forms that you would otherwise have to process with complex CGI scripts. The only other detail worth mentioning is the exception handling capabilities provided by servlets. Be sure to specify that your
doPost
and
init
methods in your HttpServlet
subclass
can each throw a ServletException
:
public void init (ServletConfig config) throws ServletException ... public void doPost ( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException ...Inside the
JdcSurvey01
servlet the doPost
method uses two try/catch
blocks to help provide either
the user or the programmer with adequate feedback when something goes
wrong. In the first try
block, the user is warned if a
problem occurs while attempting to write the survey results to the file.
The second try
block, tries to assure the results
file is properly closed before exiting the doPost
routine.
If not a stack trace is dumped to the standard error device.